﻿using System;
using System.Collections.Generic;
using System.Text;
using Kwan.Data.Mappings;
using Kwan.Core;
namespace Kwan.Data
{
    /// <summary>
    /// 条件表达式扩展操作
    /// </summary>
    public  partial class Expression
    {

        public IList<T> List<T>() where T : Mappings.DataObject, new()
        {
            return List<T>((Region)null);
        }
        public IList<T> List<T>(params string[] orderby) where T : Mappings.DataObject, new()
        {
            return List<T>(null as Region, orderby);
        }
        public IList<T> List<T>(Region region) where T : Mappings.DataObject, new()
        {
            return List<T>(region, null);
        }
        public IList<T> List<T>(Region region,params string[] orderby) where T : Mappings.DataObject,new()
        {
            ObjectMapper om = ObjectMapper.GetOM(typeof(T));
            using (IConnectinContext cc = om.Connection.GetContext())
            {
                return List<T>(cc, region, orderby);
            }
        }
        public IList<T> List<T>(IConnectinContext cc,params string[] orderby) where T : Mappings.DataObject, new()
        {
            return List<T>(cc, null, orderby);
        }
        public IList<T> List<T>(IConnectinContext cc,Region region) where T : Mappings.DataObject, new()
        {
            return List<T>(cc, region, null);
        }
        public IList<T> List<T>(IConnectinContext cc, Region region, params string[] orderby) where T : Mappings.DataObject,new()
        {
            ObjectMapper om = ObjectMapper.GetOM(typeof(T));
            string strob = null;
            if (orderby != null && orderby.Length > 0)
                strob= string.Join(",", orderby);
            return EntityBase.ExOnList<T>(cc, om.GetSelect(), this, region, strob, om.GroupBy);
        }
        public T ListFirst<T>() where T : Mappings.DataObject, new()
        {
            return ListFirst<T>((string)null);
        }
        public T ListFirst<T>(IConnectinContext cc) where T : Mappings.DataObject, new()
        {
            return ListFirst<T>(cc, null);
        }
        public T ListFirst<T>(params string[] orderby) where T : Mappings.DataObject, new()
        {

            ObjectMapper om = ObjectMapper.GetOM(typeof(T));
            using (IConnectinContext cc = om.Connection.GetContext())
            {
                return ListFirst<T>(cc, orderby);
            }

        }
        public T ListFirst<T>(IConnectinContext cc, params string[] orderby) where T:Mappings.DataObject,new()
        {
            ObjectMapper om = ObjectMapper.GetOM(typeof(T));
            string strob=null;
            if (orderby != null && orderby.Length > 0)
                strob = string.Join(",", orderby);

            return EntityBase.ExOnListFirst<T>(cc, om.GetSelect(), this, strob, om.GroupBy);
        }

        public int Delete<T>()
        {
            ObjectMapper om = ObjectMapper.GetOM(typeof(T));
            using (IConnectinContext cc = om.Connection.GetContext())
            {
               return Delete<T>(cc);
            }
        }
        public int Delete<T>(IConnectinContext cc)
        {
            ObjectMapper om = ObjectMapper.GetOM(typeof(T));
            return EntityBase.ExOnDelete(cc, om.Table, this);
        }

        /// <summary>
        /// (TRoom.entityID == tt.RoomID).Edit&lt;TRoom&lt;(d => { d.Status = 2; })
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="handler"></param>
        /// <returns></returns>
        public int Edit<T>(Action<T> handler) where T : DataObject, new()
        {
            T item = new T();
            handler(item);
            return  Edit<T>(item.GetChangeFields());
        }
        public int Edit<T>(IConnectinContext cc,Action<T> handler) where T : DataObject, new()
        {
            T item = new T();
            handler(item);
           return Edit<T>(cc,item.GetChangeFields());
        }
        public int Edit<T>(params Field[] fields) where T:DataObject,new()
        {
            ObjectMapper om = ObjectMapper.GetOM(typeof(T));
            using (IConnectinContext cc = om.Connection.GetContext())
            {
                return Edit<T>(cc,fields);
            }
        }
        public int Edit<T>(IConnectinContext cc, params Field[] fields)  where T:DataObject,new()
        {
            if (fields == null || fields.Length == 0)
                return 0;
            ObjectMapper om = ObjectMapper.GetOM(typeof(T));
            Update update = new Update(om.Table);
            update.Where = this;
            StringBuilder sb = new StringBuilder();
            foreach (Field f in fields)
            {
                update.AddField(f.Name,f.ParameterName, Mappings.PropertyCastAttribute.CastValue(om, f.Name, f.Value));
                sb.Append(f.Name); sb.Append("="); sb.Append(f.Value); sb.Append(",");
            }
            string userName = System.Web.HttpContext.Current.User.Identity.Name;
            Log.SetWriteLogType<T>(Log.LogType.All);
            Log.SetWriter<T, Log.LogWriterToFile>();
            Log.Write<T>(Log.LogType.All, userName + "修改了" + sb.ToString());

            return update.Execute(cc);
            
        }
        public int Count<T>()
        {
            ObjectMapper om = ObjectMapper.GetOM(typeof(T));

            using (IConnectinContext cc = om.Connection.GetContext())
            {
                return Count<T>(cc);
            }
        }
        public int Count<T>(IConnectinContext cc)
        {
             ObjectMapper om = ObjectMapper.GetOM(typeof(T));
             return EntityBase.ExOnCount(cc, om.Table, this, om.GroupBy);
        }

        public RESULT Sum<RESULT, Entity>(string field)
        {
            return Sum<RESULT, Entity>(field, false);
        }
        public RESULT Sum<RESULT, Entity>(string field, bool DISTINCT)
        {
            using (IConnectinContext cc = DBContext.Context1)
            {
                return Sum<RESULT, Entity>(field, DISTINCT, cc);
            }
        }
        public RESULT Sum<RESULT, Entity>(string field, IConnectinContext cc)
        {
            return Sum<RESULT, Entity>(field, false, cc);
        }
        public RESULT Sum<RESULT, Entity>(string field, bool DISTINCT, IConnectinContext cc)
        {
            ObjectMapper om = ObjectMapper.GetOM(typeof(Entity));
            object value = EntityBase.ExOnAggregation(cc, om.Table, "Sum", field, DISTINCT, this,null);
            if(value == null || value == DBNull.Value)
                return default(RESULT);
            return (RESULT)Convert.ChangeType(value, typeof(RESULT));
        }

        public RESULT Max<RESULT, Entity>(string field)
        {
            return Max<RESULT, Entity>(field, false);
        }
        public RESULT Max<RESULT, Entity>(string field, bool DISTINCT)
        {
            using (IConnectinContext cc = DBContext.Context1)
            {
                return Max<RESULT, Entity>(field, DISTINCT, cc);
            }
        }
        public RESULT Max<RESULT, Entity>(string field, IConnectinContext cc)
        {
            return Max<RESULT, Entity>(field, false, cc);
        }
        public RESULT Max<RESULT, Entity>(string field, bool DISTINCT, IConnectinContext cc)
        {
            ObjectMapper om = ObjectMapper.GetOM(typeof(Entity));
            object value = EntityBase.ExOnAggregation(cc, om.Table, "Max", field, DISTINCT, this, null);
            if (value == null || value == DBNull.Value)
                return default(RESULT);
            return (RESULT)Convert.ChangeType(value, typeof(RESULT));
        }


        public RESULT Min<RESULT, Entity>(string field)
        {
            return Min<RESULT, Entity>(field, false);
        }
        public RESULT Min<RESULT, Entity>(string field, bool DISTINCT)
        {
            using (IConnectinContext cc = DBContext.Context1)
            {
                return Min<RESULT, Entity>(field, DISTINCT, cc);
            }
        }
        public RESULT Min<RESULT, Entity>(string field, IConnectinContext cc)
        {
            return Min<RESULT, Entity>(field, false, cc);
        }
        public RESULT Min<RESULT, Entity>(string field, bool DISTINCT, IConnectinContext cc)
        {
            ObjectMapper om = ObjectMapper.GetOM(typeof(Entity));
            object value = EntityBase.ExOnAggregation(cc, om.Table, "Min", field, DISTINCT, this, null);
            if (value == null || value == DBNull.Value)
                return default(RESULT);
            return (RESULT)Convert.ChangeType(value, typeof(RESULT));
        }


        public RESULT Avg<RESULT, Entity>(string field)
        {
            return Avg<RESULT, Entity>(field, false);
        }
        public RESULT Avg<RESULT, Entity>(string field, bool DISTINCT)
        {
            using (IConnectinContext cc = DBContext.Context1)
            {
                return Avg<RESULT, Entity>(field, DISTINCT, cc);
            }
        }
        public RESULT Avg<RESULT, Entity>(string field, IConnectinContext cc)
        {
            return Avg<RESULT, Entity>(field, false, cc);
        }
        public RESULT Avg<RESULT, Entity>(string field, bool DISTINCT, IConnectinContext cc)
        {
            ObjectMapper om = ObjectMapper.GetOM(typeof(Entity));
            object value = EntityBase.ExOnAggregation(cc, om.Table, "Avg", field, DISTINCT, this, null);
            if (value == null || value == DBNull.Value)
                return default(RESULT);
            return (RESULT)Convert.ChangeType(value, typeof(RESULT));
        }
    }
}
